package com.defang.award;

import com.defang.application.EnrollSerializer;
import com.defangit.applicant.domain.Enroll;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.laogen.jersey_util.providers.SLF4JLoggingFeature;
import com.laogen.plugins.PluginManager;

import javax.ws.rs.ext.ContextResolver;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * Created by zhangfagen on 2019/1/9.
 */
public class JacksonMapperProvider implements ContextResolver<ObjectMapper>{
    private final ObjectMapper MAPPER;
    public JacksonMapperProvider() {
        MAPPER = new ObjectMapper();
        MAPPER.registerModule(new JavaTimeModule());
        Hibernate5Module hibernate5Module=new Hibernate5Module();
        //hibernate5Module.enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING);
        MAPPER.registerModule(hibernate5Module);
        SimpleModule module=new SimpleModule();
        module.addDeserializer(LocalDateTime.class,new com.laogen.jackson.deserializer.LocalDateTimeDeserializer());
        module.addSerializer(Enroll.class,new EnrollSerializer());
        try {
            for(Class clazz: PluginManager.getInstance().getRegisteredClasses("json")) {
                JsonSerializer object=(JsonSerializer)clazz.newInstance();
                Method method=clazz.getMethod("type");
                module.addSerializer((Class<?>)method.invoke(object),object);
            };
        }catch (InstantiationException|NoSuchMethodException|IllegalAccessException|InvocationTargetException ex){
            SLF4JLoggingFeature.JERSEY_LOGGER.error(ex.getLocalizedMessage(),ex);
        }
        PluginManager.getInstance().getListeners(Module.class)
                .forEach(MAPPER::registerModule);
//        module.addSerializer(ErrorMessage.class, ErrorMessageSerial.getInstance());
        MAPPER.registerModule(module);
        MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }

    @Override
    public ObjectMapper getContext(Class<?> aClass) {
        return MAPPER;
    }
}
